#include <stdio.h>
#include <unistd.h>

#include <pthread.h>

#define LOG_TAG    "mian"
#define LOG_LVL    ELOG_LVL_VERBOSE
#include <elog.h>

#include "cJSON.h"
#include "webclient.h"

#include "msg_queue.h"

struct msg_queue *mq = NULL;

void *mq_send_thread(void *arg)
{
    // tcp_server();
    int ret = 0;
    uint32_t cnt = 0;
    while (1) {
        sleep(1);
        log_d("Hello mq_send_thread!");
        cnt ++;
        ret = msg_queue_send(mq, &cnt, sizeof(int));
        if (ret != 0) {
            log_e("msg_queue_send error. error_code = %d", ret);
            break;
        }
        log_d("%d", cnt);
    }

    log_d("mq_send_thread exit!");
    return NULL;
}

/* 
加入 asan 后，会报 stack-buffer-overflow
原因：
    上层用了 int cnt; &cnt,
    memcpy(msg, queue->data + queue->head * queue->msg_size, queue->msg_size);
    溢出了。
 */
void *mq_recv_thread(void *arg)
{
    int ret = 0;
    uint32_t cnt = 0;
    while(1) {
        sleep(1);
        log_d("Hello mq_recv_thread!");
        ret = msg_queue_recv(mq, &cnt, sizeof(int));
        if (ret != 0) {
            log_e("msg_queue_recv error. error_code = %d", ret);
            break;
        }

        log_d("%d", cnt);
    }

    log_d("mq_recv_thread exit!");
    return NULL;
}

int test_init(void)
{
    int ret = 0;
    pthread_t mq_send_tid;
    pthread_t mq_recv_tid;

    mq = msg_queue_create(sizeof(int), 10);
    if (mq == NULL) {
        log_e("msg_queue_create error.");
        return -1;
    }

    ret = pthread_create(&mq_send_tid, NULL, mq_send_thread, NULL);
    if (ret != 0) {
        printf("pthread_create error. error_code = %d\n", ret);
        return -1;
    }

    ret = pthread_create(&mq_send_tid, NULL, mq_recv_thread, NULL);
    if (ret != 0) {
        log_e("pthread_create error. error_code = %d", ret);
        return -1;
    }

    return 0;
}

void test_cjson(void)
{
    // char *my_json_string = "{\"name\":\"zhangsan\",\"age\":18,\"sex\":\"male\"}";
    // cJSON *root = cJSON_Parse(my_json_string);
    // if(root == NULL) {
    //     printf("parse json failed\n");
    //     return;
    // }
    // cJSON *item = cJSON_GetObjectItem(root, "name");
    // if (item == NULL || item->type != cJSON_String) {
    //     printf("get item failed\n");
    //     return;
    // }
    // printf("name: %s\n", item->valuestring);
    // cJSON_Delete(root);


    // cJSON *root = NULL;
    // cJSON *fmt = NULL;
    // root = cJSON_CreateObject();
    // cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
    // cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject());
    // cJSON_AddStringToObject(fmt, "type", "rect");
    // cJSON_AddNumberToObject(fmt, "width", 1920);
    // cJSON_AddNumberToObject(fmt, "height", 1080);
    // cJSON_AddFalseToObject (fmt, "interlace");
    // cJSON_AddNumberToObject(fmt, "frame rate", 24);
    // char *out = cJSON_Print(root);
    // cJSON_Delete(root);
    // cJSON_Minify(out);
    // if (out) {
    //     printf("%s\n", out);
    //     free(out);
    // }

    // cJSON *root = NULL;
    // cJSON *array = NULL;
    // root = cJSON_CreateObject();
    // cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));
    // cJSON_AddItemToObject(root, "format", array = cJSON_CreateArray());
    // cJSON_AddItemToArray(array, cJSON_CreateString("rect"));
    // cJSON_AddItemToArray(array, cJSON_CreateNumber(1920));
    // cJSON_AddItemToArray(array, cJSON_CreateNumber(1080));
    // cJSON_AddItemToArray(array, cJSON_CreateFalse());
    // cJSON_AddItemToArray(array, cJSON_CreateNumber(24));
    // char *out = cJSON_PrintUnformatted(root);
    // cJSON_Delete(root);
    // if (out) {
    //     printf("%s\n", out);
    //     free(out);
    // }

    // const char *strings[7] =
    // {
    //     "Sunday",
    //     "Monday",
    //     "Tuesday",
    //     "Wednesday",
    //     "Thursday",
    //     "Friday",
    //     "Saturday"
    // };
    // cJSON *root = NULL;
    // root = cJSON_CreateStringArray(strings, 7);
    // char *out = cJSON_PrintUnformatted(root);
    // cJSON_Delete(root);
    // if (out) {
    //     printf("%s\n", out);
    //     free(out);
    // }

    // 创建一个 JSON 对象
    cJSON *root = cJSON_CreateObject();
    cJSON *item = cJSON_CreateBool(true);
    cJSON_AddItemToObject(root, "example", item);

    // 打印原始 JSON 对象
    char *json_str = cJSON_Print(root);
    printf("Original JSON: %s\n", json_str);
    free(json_str);

    // 修改 JSON 对象的布尔值
    item->type = cJSON_False;
    item->valueint = 0;

    // 打印修改后的 JSON 对象
    json_str = cJSON_Print(root);
    printf("Modified JSON: %s\n", json_str);
    free(json_str);

    // 释放内存
    cJSON_Delete(root);

}

int main(void)
{
    //log Init
    elog_init();
    elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
    elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
    elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
    elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
    elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_T_INFO | ELOG_FMT_P_INFO));
    elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_T_INFO | ELOG_FMT_P_INFO));
    elog_start();

    uint8_t buf[256]= {0};
    int i = 0;

    for (i = 0; i < sizeof(buf); i++)
    {
        buf[i] = i;
    }

    // test_init();

    log_a("Hello EasyLogger!");
    log_e("Hello EasyLogger!");
    log_w("Hello EasyLogger!");
    log_i("Hello EasyLogger!");
    log_d("Hello EasyLogger!");
    log_v("Hello EasyLogger!");
    elog_hexdump("test", 16, buf, sizeof(buf));


    test_cjson();

    while(1)
    {
        // test_http();

        // tcp_server();

        sleep(1);
    }
}
